/**
 * Copyright 2010 Butin Kirill <kiryaka@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.flexupload.service;

import java.io.IOException;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.flexupload.controller.UploadController;
import org.flexupload.model.FileInfo;
import org.flexupload.model.FilePart;
import org.flexupload.model.ServerReply;

import flex.messaging.FlexContext;

@Component("uploadService")
public class UploadServiceImpl implements UploadService {
	private final static Logger log = Logger.getLogger(UploadService.class);
	private String storagePath;
	private String session = null;
	private UploadController uploadController;
	
	@Autowired
	public void setUploadController(UploadController uploadController){
		this.uploadController = uploadController;
	}
	
	@Autowired
	public void setStoragePath(String storagePath) {
		this.storagePath = storagePath;
	}	
	
	public ServerReply startSession() {
		return new ServerReply(null, ServerReply.TYPE_START_SESSION);
	}
	
	public ServerReply startUpload(FileInfo fileInfo){
		try{
			log.info("Start upload: "+fileInfo.getName());
			fileInfo = uploadController.createTempFile(fileInfo);
		}catch (Exception e){
			return createError(fileInfo, e, ServerReply.TYPE_START_UPLOAD);
		}
		log.info("Returning start upload responce for: " + fileInfo.getName());
		
		// Test block. On local server, flex file.load is longer than upload, so upload is one threaded and we can't see multithread errors.
		// With this block we sleep a second before start to get files. so flex can load files;
		//try {Thread.sleep(500);}catch(InterruptedException e){}
		return new ServerReply(fileInfo, ServerReply.TYPE_START_UPLOAD);
	}

	public ServerReply uploadFilePart(FileInfo fileInfo, FilePart filePart){
		try {
			log.info("Upload file part: "+fileInfo.getName()+" from " + filePart.getFileOffset() + " by " + filePart.getLength());
			fileInfo = uploadController.saveFilePart(fileInfo, filePart);
			
		} catch (IOException e) {
			return createError(fileInfo, e, ServerReply.TYPE_SAVE_PART);
		}
		log.info("Returning file part responce for: " + fileInfo.getName());
		//try {Thread.sleep(500);}catch(InterruptedException e){}
		return new ServerReply(fileInfo, filePart);
	}	
	
	public ServerReply finishUpload(FileInfo fileInfo) {
		try {
			log.info("Finish upload: "+fileInfo.getName());
			uploadController.moveFileFromTempTo(fileInfo, getStoragePath() + "/" + getSession());
		} catch (IOException e) {
			return createError(fileInfo, e, ServerReply.TYPE_FINISH_UPLOAD);
		}
		log.info("Returning finish responce for: " + fileInfo.getName());
		return new ServerReply(fileInfo, ServerReply.TYPE_FINISH_UPLOAD);
	}
	
	public ServerReply finishSession() {
		return new ServerReply(null, ServerReply.TYPE_FINISH_SESSION);
	}

	private ServerReply createError(FileInfo fileInfo, Exception e, int errorType) {
		log.error("Upload service error: ", e);
		return new ServerReply(fileInfo, errorType);
	}	
	
	public String getSession(){
		if (this.session == null) 
			this.session = FlexContext.getFlexSession().getId(); 
		return this.session;
	}
	
	public void setSession(String session){
		this.session = session;
	}
	
	public String getStoragePath() {
		return this.storagePath;
	}
}
